SlackのワークフローでAWS Chatbotを動かして、EC2を開始&停止する仕組みを作ってみた
AWS Chatbotを使ってLambdaを実行すれば、SlackからEC2の開始・停止を簡単にできます。 しかし、毎回コマンドを入力して実行するのはめんどくさいです。 そこでふと思いました。
「Slackのワークフローを使えば、ボタンぽちーで終わるんちゃう?」
基本的には、下記の記事を「AWS SAMで作ってみた」&「Slackワークフローで簡易化した」内容です。
おすすめの方
- AWS ChatbotでEC2を開始・停止したい方
- AWS ChatbotでLambdaを実行したい方
- AWS ChatbotでRead系のAWSコマンドを実行したい方
- AWS SAM(CloudFormation)でAWS ChatbotとLambdaを作りたい方
- SlackのワークフローでAWS Chatbotのコマンドを実行したい方
前提
- Amazon EC2インスタンスは作成済みとします
AWS Chatbotを準備する
Slackワークスペースの認証とワークスペースID取得
WebコンソールでAWS Chatbotにアクセスし、ワークスペースを追加します。下記のワークスペースIDはあとで必要なのでメモしておきます。
SlackチャンネルIDを取得
任意のチャンネルのリンクを取得します。
このリンクの最後の文字列を使います。下記例だとABCD1234
がチャンネルIDです。
https://classmethod.slack.com/archives/ABCD1234
Lambdaを作成する
SAM Init
sam init \ --runtime python3.8 \ --name Slack-EC2-Command \ --app-template hello-world \ --package-type Zip
SAMテンプレート
下記を作成しています。
- AWS Chatbotのチャンネル設定
- AWS Chatbot用のIAMロール
- Lambda(開始・停止)
- CloudWatch logs
AWS Chatbot用のIAMロールには、最低限の権限のみを付与しています。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Slack-EC2-Command Parameters: Env: Type: String Default: Env SlackWorkspaceId: Type: String SlackEc2ChannelId: Type: String Resources: Ec2SlackChatbot: Type: AWS::Chatbot::SlackChannelConfiguration Properties: ConfigurationName: !Sub xxx-ec2-slack-chatbot-${Env} IamRoleArn: !GetAtt Ec2SlackChatbotIamRole.Arn LoggingLevel: INFO SlackWorkspaceId: !Ref SlackWorkspaceId SlackChannelId: !Ref SlackEc2ChannelId Ec2SlackChatbotIamRole: Type: AWS::IAM::Role Properties: RoleName: !Sub xxx-ec2-slack-chatbot-role-${Env} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: chatbot.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: !Sub xxx-ec2-slack-chatbot-policy-${Env} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - lambda:invokeAsync - lambda:invokeFunction Resource: - !GetAtt StartEc2Function.Arn - !GetAtt StopEc2Function.Arn - Effect: Allow Action: - ec2:DescribeInstanceStatus Resource: - "*" StartEc2Function: Type: AWS::Serverless::Function Properties: FunctionName: !Sub xxx-start-ec2-${Env} CodeUri: start_ec2/ Handler: app.lambda_handler Policies: - arn:aws:iam::aws:policy/AmazonEC2FullAccess Runtime: python3.8 Timeout: 10 StartEc2FunctionLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /aws/lambda/${StartEc2Function} StopEc2Function: Type: AWS::Serverless::Function Properties: FunctionName: !Sub xxx-stop-ec2-${Env} CodeUri: stop_ec2/ Handler: app.lambda_handler Policies: - arn:aws:iam::aws:policy/AmazonEC2FullAccess Runtime: python3.8 Timeout: 10 StopEc2FunctionLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub /aws/lambda/${StopEc2Function}
Labmdaコード
開始用のLambda
import boto3 ec2 = boto3.client('ec2') instances_ids = ['i-xxxxx'] def lambda_handler(event, context): ec2.start_instances(InstanceIds=instances_ids) print(f'start instance: {instances_ids}')
停止用のLambda
import boto3 ec2 = boto3.client('ec2') instances_ids = ['i-xxxxx'] def lambda_handler(event, context): ec2.stop_instances(InstanceIds=instances_ids) print(f'stop instance: {instances_ids}')
デプロイ
--parameter-overrides
部分は、適宜変更してください。
aws cloudformation package \ --template-file template.yaml \ --output-template-file packaged.yaml \ --s3-bucket cm-fujii.genki-deploy aws cloudformation deploy \ --template-file packaged.yaml \ --stack-name chatbot-ec2-command-stack \ --capabilities CAPABILITY_NAMED_IAM \ --parameter-overrides \ Env=dev \ SlackWorkspaceId=XYZXYZ \ SlackEc2ChannelId=ABCD1234 \ --no-fail-on-empty-changeset
SlackでAWSアプリを招待して、動作を確認する
AWSアプリを招待する
Slackの該当チャンネルで/invite @aws
を実行し、AWSアプリを招待します。
インスタンス状態を確認する(停止中?)
下記コマンドを実行します。初回のみ、リージョンを指定します。
@aws ec2 describe-instance-status --instance-ids i-xxxx --include-all-instances true --region ap-northeast-1
EC2インスタンスは、ストップ状態でした。なお、AWSアカウント等の一部情報は黒塗りしています。
EC2開始コマンドを実行する
下記で実行します。
@aws lambda invoke xxx-start-ec2-dev
実行すると、AWS Chatbotから「ええんか?」と聞かれるので、「Yes」を選択します。
無事に実行できました。
インスタンス状態を確認する(開始した?)
下記コマンドを実行します。
@aws ec2 describe-instance-status --instance-ids i-xxxx --include-all-instances true
EC2インスタンスが開始しました。
EC2停止コマンドを実行する
下記で実行します。
@aws lambda invoke xxx-stop-ec2-dev
実行すると、AWS Chatbotから「ええんか?」と聞かれるので、「Yes」を選択します。
インスタンス状態を確認する(停止した?)
下記コマンドを実行します。
@aws ec2 describe-instance-status --instance-ids i-xxxx --include-all-instances true
EC2インスタンスが停止しました。
SlackのワークフローでAWS Chatbotを実行する
ワークフローを作成する
EC2を開始するワークフロー
下記のワークフローを作成します。
@aws
部分が認識されない場合は、再入力など試してください。
また、コマンド部分に「by Name」みたいな文字を付与すると、Lambda実行に失敗するので、コマンドのみを記載しています。
EC2を停止するワークフロー
下記のワークフローを作成します。
EC2の状態を確認するワークフロー
下記のワークフローを作成します。
Slackショートカットの様子
作成したワークフローが表示されています。
Slackワークフローを実行する
EC2を開始する様子
EC2の状態を確認する様子
EC2を停止する様子
おまけ: 開始と停止を分かりやすくする
ワークフローを下記のようにすれば、メッセージ投稿も可能です。
ワークフローを実行した様子です。
さいごに
便利、かつ、楽になりました。エンジニア以外でも使いやすくなったと思います。